import { prisma } from '@src/common/database';
import type { UserWallet, PointLedger, LedgerReason, LedgerRelated } from '@prisma/client';

/**
 * 数据库工具类
 * 提供常用的数据库操作方法
 */
export class DatabaseUtils {

  /**
   * 检查数据库连接
   */
  static async checkConnection(): Promise<boolean> {
    try {
      await prisma.$queryRaw`SELECT 1`;
      return true;
    } catch (error) {
      console.error('Database connection failed:', error);
      return false;
    }
  }

  /**
   * 获取用户钱包余额
   */
  static async getUserWalletBalance(userId: bigint): Promise<bigint> {
    const wallet = await prisma.userWallet.findUnique({
      where: { userId },
    });
    return wallet?.pointsBalance || BigInt(0);
  }

  /**
   * 创建用户钱包（如果不存在）
   */
  static async createUserWalletIfNotExists(userId: bigint): Promise<UserWallet> {
    return await prisma.userWallet.upsert({
      where: { userId },
      update: {},
      create: {
        userId,
        pointsBalance: BigInt(0),
      },
    });
  }

  /**
   * 更新用户钱包余额（带事务）
   */
  static async updateWalletBalance(
    userId: bigint,
    deltaPoints: bigint,
    reason: LedgerReason,
    relatedType: LedgerRelated = 'other',
    relatedId?: bigint,
    note?: string
  ): Promise<{ wallet: UserWallet; ledger: PointLedger }> {
    return await prisma.$transaction(async (tx) => {
      // 确保钱包存在
      await tx.userWallet.upsert({
        where: { userId },
        update: {},
        create: {
          userId,
          pointsBalance: BigInt(0),
        },
      });

      // 更新钱包余额
      const wallet = await tx.userWallet.update({
        where: { userId },
        data: {
          pointsBalance: {
            increment: deltaPoints,
          },
        },
      });

      // 记录账本
      const ledger = await tx.pointLedger.create({
        data: {
          userId,
          deltaPoints,
          reason,
          relatedType,
          relatedId,
          note,
        },
      });

      return { wallet, ledger };
    });
  }

  /**
   * 获取用户信息（包含钱包）
   */
  static async getUserWithWallet(userId: bigint) {
    return await prisma.user.findUnique({
      where: { id: userId },
      include: {
        wallet: true,
      },
    });
  }

  /**
   * 获取频道信息（包含所有者）
   */
  static async getChannelWithOwner(channelId: bigint) {
    return await prisma.channel.findUnique({
      where: { id: channelId },
      include: {
        owner: {
          select: {
            id: true,
            email: true,
            role: true,
            status: true,
            avatarUrl: true,
          },
        },
      },
    });
  }

  /**
   * 获取视频信息（包含频道和聊天室）
   */
  static async getVideoWithDetails(videoId: bigint) {
    return await prisma.video.findUnique({
      where: { id: videoId },
      include: {
        channel: {
          include: {
            owner: {
              select: {
                id: true,
                email: true,
                role: true,
                status: true,
                avatarUrl: true,
              },
            },
          },
        },
        chatRooms: {
          include: {
            presets: {
              where: { isActive: true },
              orderBy: { sortOrder: 'asc' },
            },
          },
        },
      },
    });
  }

  /**
   * 获取直播间信息（包含频道）
   */
  static async getLiveRoomWithDetails(liveRoomId: bigint) {
    return await prisma.liveRoom.findUnique({
      where: { id: liveRoomId },
      include: {
        channel: {
          include: {
            owner: {
              select: {
                id: true,
                email: true,
                role: true,
                status: true,
                avatarUrl: true,
              },
            },
          },
        },
        presets: {
          where: { isActive: true },
          orderBy: { sortOrder: 'asc' },
        },
      },
    });
  }

  /**
   * 分页查询
   */
  static getPaginationParams(page: number = 1, limit: number = 20) {
    const skip = (page - 1) * limit;
    return {
      skip,
      take: limit,
    };
  }

  /**
   * 构建分页响应
   */
  static buildPaginationResponse<T>(
    data: T[],
    total: number,
    page: number,
    limit: number
  ) {
    const totalPages = Math.ceil(total / limit);
    return {
      data,
      pagination: {
        page,
        limit,
        total,
        totalPages,
        hasNext: page < totalPages,
        hasPrev: page > 1,
      },
    };
  }
}

export default DatabaseUtils;
